#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <ctime>
#include "RingQueue.hpp"
#include "SmartMutex.hpp"
using namespace std;

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

void *consumer(void *arg)
{
    RQueue<int> *rq = static_cast<RQueue<int> *>(arg);

    sleep(1);

    while (true)
    {
        int data;
        rq->Pop(&data);

        {
            SmartMutex smartmutex(&mutex);
            cout << "consumer: " << data << "   " << pthread_self() << endl;
        }
    }

    return nullptr;
}

void *produser(void *arg)
{
    RQueue<int> *rq = static_cast<RQueue<int> *>(arg);

    while (true)
    {
        int data = rand();
        rq->Push(data);

        {
            SmartMutex smartmutex(&mutex);
            cout << "produser : " << data << "   " << pthread_self() << endl;
        }
        sleep(1);
    }

    return nullptr;
}

int main()
{
    srand((unsigned)time(nullptr));
    RQueue<int> *rq = new RQueue<int>();
    pthread_t c[2], p[3];
    pthread_create(&c[0], nullptr, consumer, rq);
    pthread_create(&c[1], nullptr, consumer, rq);
    pthread_create(&p[0], nullptr, produser, rq);
    pthread_create(&p[1], nullptr, produser, rq);
    pthread_create(&p[2], nullptr, produser, rq);

    pthread_join(c[0], nullptr);
    pthread_join(c[1], nullptr);
    pthread_join(p[0], nullptr);
    pthread_join(p[1], nullptr);
    pthread_join(p[2], nullptr);
    return 0;
}